<?php
class Feed extends Podcast {
	private $feedContent;

	function __construct($podcast="") {
		($podcast != "") ? self::$podcast = $podcast : $podcast;

		// give the feed a few moments to read the sources
		ini_set('max_execution_time', "120");
	}

	public function showContent($modified=true) {
		// general .torrent-feed or certain podcast-feed?
		if(self::$podcast != "torrent") {
			$this->readOriginalFeed();
			$this->generateNewFeed($modified);

			if($modified) {
				// save new feed in cache
				file_put_contents(self::$feedcache."/".self::$podcast.".cache", $this->feedContent);
			}
		} else {
			$this->generateTorrentFeed();
		}

		header("Content-Type: application/rss+xml");
		echo $this->feedContent;
	}

	public function getCachedContent($original=false) {
		($original) ? $original = ".ori" : $original = "";
		$cache = @file_get_contents(self::$feedcache."/".self::$podcast."$original.cache");
		return $cache;
	}

	private function readOriginalFeed() {
		// get feed url from db and read it
		$query = "SELECT feed FROM `pp_podcasts` WHERE tag = '".self::$podcast."';";
		$result = self::$db->query($query);

		if(!@mysql_num_rows($result)) {
			$this->feedContent = "";
		} else {
			list($feedurl) = mysql_fetch_array($result);
			$this->feedContent = $this->readUrl($feedurl);

			// if feed could not be read, get content from cache
			// otherwise write new content to cache
			$cache = self::$feedcache."/".self::$podcast.".ori.cache";

			if($this->feedContent != "") {
				// save original feed in cache
				file_put_contents($cache, $this->feedContent);
			} else {
				$this->feedContent = @file_get_contents($cache);
			}
		}
	}

	private function generateNewFeed($modifed) {
		// if there was an error, feedContent should be ""
		if($this->feedContent != "") {
			$wholeContentXml = new SimpleXMLElement($this->feedContent);
			$delIndex = array();

			foreach ($wholeContentXml->channel as $channel) {

				$inc = 0;
				foreach ($channel->item as $episode) {
					$fileurl = $episode->enclosure["url"][0];

					$pattern = "#.*/(.*)\.[ampAMP34]{3}#";
					$filename = preg_replace($pattern, "$1", $fileurl);

					// check if every item has length attribute (for stupid podcatcher)
					if($episode->enclosure["length"][0] == null) {
						@$episode->enclosure->addAttribute("length", "0");
					}

					// should the feed be modified (check all episodes)?
					if($modifed) {
						// file already in cache? if not delete this episode from feed
						// otherwise change the fileurl to own server
						$name = $this->podcastNameInCache($filename);
						if($name == "") {
							array_push($delIndex, $inc);
						} else {
							unset($episode->enclosure["url"]);
							$episode->enclosure->addAttribute("url", ROOT.'feed/'.self::$podcast.'/'.$name);
						}
					}

					$inc++;
				}
			}

			// delete all marked episodes
			foreach ($delIndex as $index) {
				$channel->item[$index] = null;
			}

			$newXml = $wholeContentXml->asXML();

			// clean from created empty item elements
			$newXml = str_replace("<item></item>", "", $newXml);

			// clean from itunes:new-feed-url
			$newXml = preg_replace("#<itunes:new-feed-url>.*</itunes:new-feed-url>#", "", $newXml);

		} else {
			$newXml = "<?xml version='1.0' encoding='UTF-8'?>\n";
			$newXml .= '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">';
			$newXml .= '<channel><title>ERROR: "'.self::$podcast.'"</title>';
			$newXml .= '</channel></rss>';
		}

		$this->feedContent = $newXml;
	}

	private function podcastNameInCache($filename) {
		$res = "";

		foreach (self::$files as $cachedFile) {
			if($cachedFile["filename"] == $filename) {
				$res = $cachedFile["filename"].$cachedFile["extension"];
				break;
			}
		}

		return $res;
	}

	private function generateTorrentFeed() {
		// get all feeds
		$query = "SELECT tag, name, torrentfeed, last FROM `pp_podcasts` WHERE feed <> torrentfeed ORDER BY last LIMIT 0,5;";
		$res = self::$db->query($query);

		$allItems = array();
		$feed = array();
		$i = 0;

		while($data = mysql_fetch_assoc($res)) {
			$feed[$i]["content"] = $this->readUrl($data["torrentfeed"]);
			$feed[$i]["name"] = $data["name"];

			// update the time
			$query = "UPDATE `pp_podcasts` SET `last` = '".time()."' WHERE tag = '".$data["tag"]."';";
			self::$db->query($query);

			$i++;
		}

		// catch all item (episodes)
		for($i = 0; $i < count($feed); $i++) {
			$pattern = "#.*(<item>.*</item>)#Us";

			if(preg_match_all($pattern, $feed[$i]["content"], $t)) {
				foreach($t[1] as $item) {
					$item = $this->gutItem($item);

					if($item != "") {
						// append podcast name at the front
						$item = str_replace("<title>", "<title>".$feed[$i]["name"].": ", $item);

						array_push($allItems, $item);
					}
				}
			}
		}

		// put all together to one xml
		$xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
		$xml .= '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">';
		$xml .= '<channel><title>PodcastProject '.date("H:i", time()).'</title>';

		foreach ($allItems as $item) {
			$xml .= $item;
			$xml .= "\n";
		}

		$xml .= "</channel></rss>";

		$this->feedContent = $xml;

	}

	private function gutItem($item) {
		// you need title, pubdate, enclosure and should have guid
		preg_match("#<title.*</title>#", $item, $t);
		$title = @$t[0];

		preg_match("#<pubDate.*</pubDate>#", $item, $t);
		$pubDate = @$t[0];

		preg_match("#<guid.*</guid>#", $item, $t);
		$guid = @$t[0];

		preg_match('#<enclosure.*application/x-bittorrent.*/>#', $item, $t);
		$enclosure = @$t[0];

		// what? no guid? tztztz, use the audio url
		if($guid == null) {
			$guid = preg_replace('#.*url="(.*\.torrent)".*#', "<guid isPermaLink=\"false\">$1</guid>", $enclosure);
		}

		// only return correct item
		if($title != null && $enclosure != null && $pubDate != null) {
			$item = "\n<item>";
			$item .= "$title\n$pubDate\n$guid\n$enclosure\n";
			$item .= "</item>\n";
		} else {
			$item = "";
		}

		return $item;
	}

	private function readUrl($url) {
		$cookie = "feedcookie";
		$ch = curl_init();

		@curl_setopt($ch, CURLOPT_URL, $url);
		@curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
		@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		@curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		@curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
		@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		@curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
		@curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);

		$result = curl_exec ($ch);
		curl_close($ch);
		@unlink($cookie);

		return $result;
	}
}

?>
